package dbrpc

import (
	"bytes"
	"context"
	"database/sql"
	"dub/define/grpcmodel"
	"dub/utils"
	"strconv"
	"strings"
)

//与权限有关的数据库操作
type DbRpcAuth struct {
	log *utils.Logger
}

//查询所有的权限信息
func (a *DbRpcAuth) FindAll(ctx context.Context, args *grpcmodel.ModelDbRpcAuthReqFind) (reply *grpcmodel.ModelDbRpcAuthResFindAll, err error) {
	reply = &grpcmodel.ModelDbRpcAuthResFindAll{}
	dbAccounts := NewDbProxy().Get(DB_Accounts)
	sql_str := "select authId,authUrl,authMicroServerName from dubauthority"
	a.log.Infof("def_func_db_auth.go FindAllAuths method exec %s params is \n", sql_str)
	rows, err := dbAccounts.Query(sql_str)

	for {
		if err == sql.ErrNoRows {
			err = nil
			reply.Err = 1
			break
		}
		if err != nil && err != sql.ErrNoRows {
			reply.Err = 2
			a.log.Errorf("def_fun_db_auth.go FindAllAuths method dbAccounts.Query err.%v\n", err)
			break
		}

		defer rows.Close()
		reply.Auths = make([]*grpcmodel.ModelDbRpcAuth, 0)
		for rows.Next() {
			var (
				authId                       sql.NullInt64
				authUrl, authMicroServerName sql.NullString
			)
			err := rows.Scan(&authId, &authUrl, &authMicroServerName)
			if err != nil {
				reply.Err = 2
				a.log.Errorf("def_fun_db_auth.go FindAllAuths method rows.Scan err.\n", err)
				continue
			}
			auth := &grpcmodel.ModelDbRpcAuth{}
			if authId.Valid {
				auth.AuthId = uint32(authId.Int64)
			}
			if authUrl.Valid {
				auth.AuthUrl = authUrl.String
			}
			if authMicroServerName.Valid {
				auth.AuthMicroServerName = authMicroServerName.String
			}
			reply.Auths = append(reply.Auths, auth)
		}
		break
	}
	return
}

//根据查询条件相应的权限
func (a *DbRpcAuth) Find(ctx context.Context, args *grpcmodel.ModelDbRpcAuthReqFind) (reply *grpcmodel.ModelDbRpcAuthResFind, err error) {
	reply = &grpcmodel.ModelDbRpcAuthResFind{}
	params := make([]interface{}, 0)
	sql_str := bytes.Buffer{}

	sql_str.WriteString("select au.authId,au.authName,au.authPreId,au.authShowStatus,au.authMicroServerName" +
		",au.authType, au.authUrl,ra.roleAuthConf,au.authNeedUrlIds from dubauthority as au" +
		" LEFT JOIN dubroleauth as ra on au.authId=ra.authId where ra.roleAuthStatus=1 and au.authStatus=1")
	if args.GetRoleId() > 0 {
		sql_str.WriteString(" and ra.roleId=?")
		params = append(params, args.GetRoleId())
	}
	if args.GetMicroServer() != "" {
		sql_str.WriteString(" and au.authMicroServerName=?")
		params = append(params, args.GetMicroServer())
	}
	sql_str.WriteString(" order by au.authAddTime asc")

	dbAccounts := NewDbProxy().Get(DB_Accounts)
	sql_buf := sql_str.String()
	a.log.Infof("def_func_db_auth.go Find method exec %s params is %+v\n", sql_buf, params)
	for {
		rows, err := dbAccounts.Query(sql_buf, params...)

		if err == sql.ErrNoRows {
			err = nil
			reply.Err = 1
			break
		}
		if err != nil && err != sql.ErrNoRows {
			reply.Err = 2
			a.log.Errorf("def_fun_db_auth.go Find method dbAccounts.Query err.%v\n", err)
			break
		}

		defer rows.Close()
		reply.Rows = make([]*grpcmodel.ModelDbRpcAuth, 0)
		for rows.Next() {
			var (
				authId, authPreId, authShowStatus, authType, roleAuthConf sql.NullInt64
				authName, authMicroServerName, authUrl, authNeedUrl       sql.NullString
			)
			err := rows.Scan(&authId, &authName, &authPreId, &authShowStatus, &authMicroServerName, &authType, &authUrl, &roleAuthConf, &authNeedUrl)
			//err := rows.Scan(&auth.AuthId, &auth.AuthName, &auth.AuthPreId, &auth.AuthShowStatus, &auth.AuthMicroServerName, &auth.AuthType, &auth.AuthUrl)
			if err != nil {
				reply.Err = 2
				a.log.Errorf("def_fun_db_auth.go Find method rows.Scan err.%v\n", err)
				continue
			}
			auth := grpcmodel.ModelDbRpcAuth{}
			if authId.Valid {
				auth.AuthId = uint32(authId.Int64)
			}
			if authName.Valid {
				auth.AuthName = authName.String
			}
			if authPreId.Valid {
				auth.AuthPreId = uint32(authPreId.Int64)
			}
			if authShowStatus.Valid {
				auth.AuthShowStatus = uint32(authShowStatus.Int64)
			}
			if authMicroServerName.Valid {
				auth.AuthMicroServerName = authMicroServerName.String
			}
			if authType.Valid {
				auth.AuthType = uint32(authType.Int64)
			}
			if authUrl.Valid {
				auth.AuthUrl = authUrl.String
			}
			if roleAuthConf.Valid {
				auth.RoleAuthConf = uint32(roleAuthConf.Int64)
			}
			if authNeedUrl.Valid {
				auth.AuthNeedUrl = authNeedUrl.String
				ids := strings.Split(authNeedUrl.String, ",")
				if len(ids) > 0 {
					auth.AuthNeedUrls = make([]uint32, 0)
					for _, id := range ids {
						if id != "" {
							if ind, err := strconv.Atoi(id); err != nil {
								a.log.Errorf("def_fun_db_auth.go FindAuthByRoleId method find data err au.authNeedUrl column is not int.%v\n", err)
							} else {
								auth.AuthNeedUrls = append(auth.AuthNeedUrls, uint32(ind))
							}
						}
					}
				}
			}

			reply.Rows = append(reply.Rows, &auth)
		}
		break
	}
	return
}

var d_dbRpcAuth *DbRpcAuth

func NewDbRpcAuth() *DbRpcAuth {
	if d_dbRpcAuth == nil {
		d_dbRpcAuth = &DbRpcAuth{
			log: utils.NewLogger(),
		}
	}
	return d_dbRpcAuth
}
